﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KMS.Core
{
    public partial class ServiceBase<T>
    {
        protected virtual bool OnBeforeDeleteByKey(DeleteEventArgs arg)
        {
            return true;
        }

        protected virtual void OnAfterDeleteByKey(DeleteEventArgs arg)
        {

        }
        public int Delete(dynamic key)
        {
            var result = 0;
            var query = new Query<T>();

            var keyColumns = typeof(T).GetSelectClause().Where(x => x.Identity || x.IsPrimaryKey).ToList();
            if (!keyColumns.Any())
            {
                throw new ArgumentException("Entity must have at least one [Key] property");
            }
            if (keyColumns.Count() > 1)
            {
                throw new Exception("Get<T> only supports an entity with a single [Key] property");
            }
            query.Filter = new IdCriteria(key, keyColumns.First().Name);

            QueryExcute(
                db =>
                {
                    var rtnBefore = this.OnBeforeDeleteByKey(new DeleteEventArgs() { Db = db, Data = key });
                    if (!rtnBefore) return;
                    result = db.DeleteQuery(query);
                    this.OnAfterDeleteByKey(new DeleteEventArgs() { Db = db, Data = key, ExecuteValue = result });
                }
                );

            return result;
        }

        public int Delete(Criteria filter, Func<DeleteEventArgs, bool> beforeEvent = null, Action<DeleteEventArgs> afterEvent = null)
        {
            var result = 0;
            var query = new Query<T>(); 
            query.Filter = filter;
            QueryExcute(
                db =>
                {
                    if (beforeEvent != null)
                    {
                        var rtnBefore = beforeEvent(new DeleteEventArgs() { Db = db, Data = filter });
                        if (!rtnBefore)
                        {
                            return;
                        }
                    }
                  
                    result = db.DeleteQuery(query);
                    if (afterEvent != null)
                    {
                        afterEvent(new DeleteEventArgs() { Db = db, Data = filter, ExecuteValue = result });
                    } 
                }
             );
            return result;
        }
    }
}
